﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Threading;
using Autofac;
using Caliburn.Micro;
using NHibernate.Cfg;
using PurchaseSales.Manage.Common.AOP;
using PurchaseSales.Manage.Model.Entities;
using PurchaseSales.Manage.Repositories;
using PurchaseSales.Manage.Services;
using PurchaseSales.Manage.ViewModels;
using PurchaseSales.Manage.Views;

namespace PurchaseSales.Manage
{
    public class AppBootstrapper : Bootstrapper
    {
        private IContainer _rootContainer;
        private ContainerBuilder _builder;
        private Task task;
        public IContainer Container { get { return _rootContainer; } }
        public AppBootstrapper()
        {
            if (!Execute.InDesignMode)
            {
                var loginView = new LoginView(LoginSuccess);
                loginView.Show();
            }
        }

        protected override void Configure()
        {

            task = Task.Factory.StartNew(() =>
                           {
                               if (_builder == null)
                                   _builder = new ContainerBuilder();

                               //注册NHIbernate模块
                               _builder.RegisterModule<NhibernateModule>();
                               //注册对象

                               _builder.RegisterInstance(new WindowManager()).As<IWindowManager>();
                               _builder.RegisterInstance(new EventAggregator()).As<IEventAggregator>();
                               _builder.RegisterType<ShellViewModel>().As<IShell>();
                               _builder.RegisterType<LoginViewModel>().As<ILoginViewModel>();

                               _builder.RegisterType<CustomerViewModel>().Named("CustomerViewModel", typeof(CustomerViewModel));
                               _builder.RegisterType<CustomerRepository>().As<ICustomerRepository>();

                               _builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>));
                               _builder.RegisterGeneric(typeof(ShowDialogViewModel<>)).As(typeof(IShowDialogViewModel<>));

                               _builder.RegisterType<CommodityViewModel>().Named("CommodityViewModel", typeof(CommodityViewModel));
                               _builder.RegisterType<CommodityRepository>().As<ICommodityRepository>();

                               _builder.RegisterType<SupplierRepository>().As<ISupplierRepository>();
                               _builder.RegisterType<SupplierViewModel>().Named("SupplierViewModel", typeof(SupplierViewModel));

                               _builder.RegisterType<PurchaseCommodityRepository>().As<IPurchaseCommodityRepository>();
                               _builder.RegisterType<PurchaseCommodityViewModel>().Named("PurchaseCommodityViewModel", typeof(PurchaseCommodityViewModel));

                               _builder.RegisterType<SalesRepository>().As<ISalesRepository>();
                               _builder.RegisterType<SalesViewModel>().Named("SalesViewModel", typeof(SalesViewModel));

                               _builder.RegisterType<AuthRoleFunctionRepository>().As<IAuthRoleFunctionRepository>();
                               _builder.RegisterType<AuthRolesRepository>().As<IAuthRolesRepository>();
                               _builder.RegisterType<AuthRoleViewModel>().Named("AuthRoleViewModel", typeof(AuthRoleViewModel));

                               _builder.RegisterType<UserRepository>().As<IUserRepository>();
                               _rootContainer = _builder.Build();
                           });
        }

        /// <summary>
        /// 登陆成功加载相应模块
        /// </summary>
        private void LoginSuccess()
        {
            task.Wait();
            ShowRootViewModel();
        }

        private void ShowRootViewModel()
        {
            IoC.Get<Configuration>();

            var shell = IoC.Get<IShell>();
            var windowManager = IoC.Get<IWindowManager>();
            windowManager.ShowWindow(shell, null);

        }

        protected override object GetInstance(Type service, string key)
        {
            object instance;
            if (string.IsNullOrWhiteSpace(key))
            {
                if (_rootContainer.TryResolve(service, out instance))
                    return instance;
            }
            else
            {
                if (_rootContainer.TryResolveNamed(key, service ?? typeof(object), out instance))
                    return instance;
            }
            throw new Exception(string.Format("Could not locate any instances of contract {0}.", key ?? service.Name));
        }

        protected override IEnumerable<object> GetAllInstances(Type serviceType)
        {
            var enumerableType = typeof(IEnumerable<>).MakeGenericType(serviceType);

            var instance = _rootContainer.Resolve(enumerableType);
            return ((IEnumerable)instance).Cast<object>();
        }
        protected override void BuildUp(object instance)
        {
            _rootContainer.InjectProperties(instance);
        }

        protected override void OnUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
        {
            //var log = log4net.LogManager.GetLogger("FileAppender");
            //if (log.IsErrorEnabled)
            //    log.Error(e.Exception);
            var logger = NLog.LogManager.GetCurrentClassLogger();
            logger.Error(e.Exception);
            base.OnUnhandledException(sender, e);
        }


    }
}
